1 using System;
2 using UnityEngine;
3 using UnityStandardAssets.CrossPlatformInput;
4
5 namespace UnityStandardAssets.Utility
6 {
7 public class SimpleMouseRotator : MonoBehaviour
8 {
9 // A mouselook behaviour with constraints which operate relative to
10 // this gameobject's initial rotation.
11 // Only rotates around local X and Y.
12 // Works in local coordinates, so if this object is parented
13 // to another moving gameobject, its local constraints will
14 // operate correctly
15 // (Think: looking out the side window of a car, or a gun turret
16 // on a moving spaceship with a limited angular range)
17 // to have no constraints on an axis, set the rotationRange to 360 or greater.
18 public Vector2 rotationRange = new Vector3(70, 70);
19 public float rotationSpeed = 10;
20 public float dampingTime = 0.2f;
21 public bool autoZeroVerticalOnMobile = true;
22 public bool autoZeroHorizontalOnMobile = false;
23 public bool relative = true;
24
25
26 private Vector3 m_TargetAngles;
27 private Vector3 m_FollowAngles;
28 private Vector3 m_FollowVelocity;
29 private Quaternion m_OriginalRotation;
30
31
32 private void Start()
33 {
34 m_OriginalRotation = transform.localRotation;
35 }
36
37
38 private void Update()
39 {
40 // we make initial calculations from the original local rotation
41 transform.localRotation = m_OriginalRotation;
42
43 // read input from mouse or mobile controls
44 float inputH;
45 float inputV;
46 if (relative)
47 {
48 inputH = CrossPlatformInputManager.GetAxis("Mouse X");
49 inputV = CrossPlatformInputManager.GetAxis("Mouse Y");
50
51 // wrap values to avoid springing quickly the wrong way from positive to negative
52 if (m_TargetAngles.y > 180)
53 {
54 m_TargetAngles.y -= 360;
55 m_FollowAngles.y -= 360;
56 }
57 if (m_TargetAngles.x > 180)
58 {
59 m_TargetAngles.x -= 360;
60 m_FollowAngles.x -= 360;
61 }
62 if (m_TargetAngles.y < -180)
63 {
64 m_TargetAngles.y += 360;
65 m_FollowAngles.y += 360;
66 }
67 if (m_TargetAngles.x < -180)
68 {
69 m_TargetAngles.x += 360;
70 m_FollowAngles.x += 360;
71 }
72
73 #if MOBILE_INPUT
74 // on mobile, sometimes we want input mapped directly to tilt value,
75 // so it springs back automatically when the look input is released.
76 if (autoZeroHorizontalOnMobile) {
77 m_TargetAngles.y = Mathf.Lerp (-rotationRange.y * 0.5f, rotationRange.y * 0.5f, inputH * .5f + .5f);
78 } else {
79 m_TargetAngles.y += inputH * rotationSpeed;
80 }
81 if (autoZeroVerticalOnMobile) {
82 m_TargetAngles.x = Mathf.Lerp (-rotationRange.x * 0.5f, rotationRange.x * 0.5f, inputV * .5f + .5f);
83 } else {
84 m_TargetAngles.x += inputV * rotationSpeed;
85 }
86 #else
87 // with mouse input, we have direct control with no springback required.
88 m_TargetAngles.y += inputH*rotationSpeed;
89 m_TargetAngles.x += inputV*rotationSpeed;
90 #endif
91
92 // clamp values to allowed range
93 m_TargetAngles.y = Mathf.Clamp(m_TargetAngles.y, -rotationRange.y*0.5f, rotationRange.y*0.5f);
94 m_TargetAngles.x = Mathf.Clamp(m_TargetAngles.x, -rotationRange.x*0.5f, rotationRange.x*0.5f);
95 }
96 else
97 {
98 inputH = Input.mousePosition.x;
99 inputV = Input.mousePosition.y;
100
101 // set values to allowed range
102 m_TargetAngles.y = Mathf.Lerp(-rotationRange.y*0.5f, rotationRange.y*0.5f, inputH/Screen.width);
103 m_TargetAngles.x = Mathf.Lerp(-rotationRange.x*0.5f, rotationRange.x*0.5f, inputV/Screen.height);
104 }
105
106 // smoothly interpolate current values to target angles
107 m_FollowAngles = Vector3.SmoothDamp(m_FollowAngles, m_TargetAngles, ref m_FollowVelocity, dampingTime);
108
109 // update the actual gameobject's rotation
110 transform.localRotation = m_OriginalRotation*Quaternion.Euler(-m_FollowAngles.x, m_FollowAngles.y, 0);
111 }
112 }
113 }